机器指令
机器指令:每一条机器语言的语句。
指令系统:全部机器指令的集合。
指令的格式是什么
- 指令码 地址码 寻址方式
指令的字长
- 固定长度、可变字长
指令的一般格式
操作码(反映机器做说明操作)
(1) 长度固定
用于指令字长较长的情况,RISC
如 IBM 370,操作码八位
(2) 长度可变
操作码分散在指令字的不同字段中。
(3) 扩展操作码技术
操作码的位数随地址数的减少而增加
三地址指令操作码每减少一种最多可多构成$2^4$种二地址指令;
二地址指令操作码每减少一种最多可多构成$2^4$种一地址指令。
思考:若给定一个指令集,要求对指令集中的指令的操作码进行编码,哪些指令的操作码用长操作码表示,哪些指令的操作码用短操作码表示?
答:一般在程序执行过程中,经常出现的高频指令可以用短操作码来表示,低频指令用长操作码表示。
地址码
(1) 四地址
$A_1$第一操作数地址
$A_2$第二操作数地址
$A_3$结果的地址
$A_4$下一条指令的地址
$(A_1)OP(A_2)→A_3$
设指令字长为32位,操作码固定为8位,4个地址字段各占6位,寻址范围为$2^6=64$。如果地址字段均指示内存的地址,则完成一条四地址指令,共需4次访存(取指令一次,取两个操作码两次,存放结果一次)。
程序计数器PC既能存放当前欲执行的指令的地址,又有计数功能,因此它能自动形成下一条指令的地址。这样,指令字中的第四地址字段$A_4$便可省去,即得三地址指令格式。
(2) 三地址
$(A_1)OP(A_2)→A_3$
4次访存,寻址范围$2^8=256$
机器在运行过程中,没必要将每次运行结果都存入主存,中间结果可以暂时存放在CPU的寄存器(如ACC)中,这样又省去一个地址字段$A_3$,从而得出二地址指令。
(3) 二地址
$(A_1)OP(A_2)→A_1$ 或 $(A_1)OP(A_2)→A_2$:4次访存
$(A_1)OP(A_2)→ACC$:3次访存
寻址范围$2^{12}=4K$
如果将一个操作数的地址隐含在运算器的ACC中,则指令字中只需给出一个地址码,构成一地址指令。
(4) 一地址
$(ACC)OP(A_1)→ACC$
2次访存
寻址范围$2^{24}=16M$
(5) 零地址
在指令字中无地址码,例如,空地址(NOP)、停机(HLT)这类指令只有操作码。而子程序返回(RET)、中断返回(IRET)这类指令没有地址码,其操作数的地址隐含在堆栈指针SP中。
指令字长
$$
指令字长决定于\begin{cases}操作码的长度\操作数地址的长度\操作数地址的个数\end{cases}
$$
指令字长固定
指令字长 = 存储字长
指令字长可变
按字节的倍数变化
操作数类型和操作种类
操作数类型
地址:无符号整数
数字:定点数、浮点数、十进制数
字符:ASCII
逻辑数:逻辑运算
数据在存储器中的存放方式
例:12345678H的存放方式
(1)
(2)
字节编址,数据在存储器中的存放方式
从任意位置开始存储
优点:不浪费存储资源。
缺点:除了访问一个字节之外,访问其它任何类型的数据都可能花费两个存储周期的时间。读写控制比较复杂。
从一个存储字的起始位置开始访问
优点:无论访问何种类型的数据,在一个周期内均可完成,读写控制简单。
缺点:严重浪费存储资源。
边界对准方式——从地址的整数倍位置开始访问
数据存放的起始地址是数据长度(按照编址单位进行计算)的整数倍。
本方案是前两个方案的折衷,在一个周期内可以完成存储访问,空间浪费也不太严重。
操作类型
- 数据传输
源 | 目的 | 例如 |
---|---|---|
寄存器 | 寄存器 | MOVE |
寄存器 | 存储器 | STORE/MOVE/PUSH |
存储器 | 寄存器 | LOAD/MOVE/POP |
存储器 | 存储器 | MOVE |
算术逻辑操作
加、减、乘、除、增1、减1、求补、浮点运算、十进制运算、与或、非、异或、位操作、位测试、位清除、位求反等。
移位操作
算术移位 逻辑移位 循环移位(带进位和不带进位)
转移
(1) 无条件转移 JMP
(2) 条件转移
结果为零转 (Z=1) JZ
结果溢出转 (O=1) JO
结果有进位转 (C=1) JC
跳过一条指令 SKP
(3) 调用和返回
(4) 陷阱(Trap)与陷阱指令
意外事故的中断
一般不提供给用户直接使用
在出现事故时,由CPU自动产生并执行(隐指令)
设置供用户使用的陷阱指令
输入输出
入:端口中的内容 → CPU的寄存器
出:CPU的寄存器 → 端口的内容
寻址方式
寻址方式:确定本条指令的操作数地址以及下一条将要执行的指令的指令地址的方式,它与硬件结构紧密相关,而且直接影响指令格式和指令功能。
$$
寻址方式\begin{cases}指令寻址\数据寻址\end{cases}
$$
指令寻址
顺序寻址
$(PC)+1→PC$
跳跃寻址
由转移指令指出
数据寻址
形式地址:指令字中的地址
有效地址:操作数的真实地址
约定:指令字长 = 存储字长 = 机器字长
立即寻址
形式地址A就是操作数
数据采用补码的形式存放。
指令执行阶段不访存
A的位数限制了立即数的范围
直接寻址
$EA=A$
有效地址由形式地址直接给出
执行阶段访问一次存储器
A的位数决定了该指令操作数的寻址范围
操作数的地址不易修改(必须修改A)
隐含寻址
操作数地址隐含在操作码中
- 指令字中少了一个地址字段,可缩短指令字长
间接寻址
$EA=(A)$
有效地址由形式地址间接提供
执行指令阶段 2次访寻
可扩大寻址范围
便于编制程序
寄存器寻址
$EA=R_i$
有效地址即为寄存器编号
执行阶段不访存,只访问寄存器,执行速度快
寄存器个数有限,可缩短指令字长
寄存器间接寻址
$EA=(R_i)$
有效地址在寄存器中
有效地址在寄存器中,操作数在存储器中,执行阶段访存1次
便于编写循环程序
基址寻址
(1) 采用专用寄存器作基址寄存器
$EA=(BR)+A$
BR为基址寄存器
可扩大寻址范围
有利于多道程序
BR内容由操作系统或管理程序确定
在程序的执行过程中BR内容不变,形式地址A可变
(2) 采用通用寄存器作基址寄存器
由用户指定哪个通用寄存器作为基址寄存器
基址寄存器的内容由操作系统确定
在程序的执行过程中$R_0$内容不变,形式地址A可变
变址寻址
$EA=(IX)+A$
IX为变址寄存器(专用)
通用寄存器也可以作为变址寄存器
可扩大寻址范围
IX的内容由用户给定
在程序的执行过程中IX内容可变,形式地址A不变
便于处理数组问题
相对寻址
$EA=(PC)+A$
A是相对于当前指令的位移量(可正可负,补码)
A的位数决定操作数的寻址范围
程序浮动
广泛用于转移指令
堆栈寻址
(1) 堆栈的特点
$$
堆栈\begin{cases}硬堆栈\ \ 多个寄存器\软堆栈\ \ 指定的存储空间\end{cases}
$$先进后出(一个入出口)
栈顶地址由SP指出
$进栈(SP)-1→SP$
$出栈(SP)+1→SP$
(2) 堆栈寻址举例
(3) SP的修改与主存编址方法有关
① 按字编址
$进栈(SP)-1→SP$
$进栈(SP)+1→SP$
② 按字节编址
存储字长16位:
$进栈(SP)-2→SP$
$进栈(SP)+2→SP$
存储字长32位:
$进栈(SP)-4→SP$
$进栈(SP)+4→SP$